﻿using AutoMapper;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using Volo.Abp;
using Volo.Abp.Application.Services;
using Volo.Abp.DependencyInjection;
using Volo.Abp.Domain.Repositories;
using Volo.Abp.Linq;
using YaAppoint.Response;

namespace YaAppoint.Appointments.Schedules
{
    [RemoteService(isEnabled: false)]
    public class ScheduleAppService(IRepository<Schedule,Guid> scheduleRepository,
                                    IRepository<Department,Guid> departmentRepository,
                                    IRepository<DeviceType,Guid> deviceTypeRepository,
                                    ScheduleManager scheduleManager,
                                    AsyncQueryableExecuter queryableExecuter,
                                    IMapper mapper
                                    ) : ApplicationService, IScheduleAppService, ITransientDependency
    {
        private readonly IRepository<Schedule, Guid> _scheduleRepository = scheduleRepository;
        IRepository<Department, Guid> _departmentRepository = departmentRepository;
        IRepository<DeviceType, Guid> _deviceTypeRepository = deviceTypeRepository;
        AsyncQueryableExecuter _queryableExecuter = queryableExecuter;
        ScheduleManager _scheduleManager = scheduleManager;
        private readonly IMapper _mapper = mapper;


        /// <summary>
        ///  获取科室设备类型下排班计划列表
        /// </summary>
        public async Task<BackJson> GetListAsync(Guid depId, Guid deviceTypeId, string? filterName)
        {
            var query = await _scheduleRepository.GetQueryableAsync();
            query = query.Where(x => x.DepartmentId == depId && x.DeviceTypeId == deviceTypeId);
            if (!string.IsNullOrEmpty(filterName))
            {
                query = query.Where(x => x.Name.Contains(filterName));
            }

            var list = _mapper.Map<List<Schedule>, List<ScheduleDto>>(await _queryableExecuter.ToListAsync(query));

            return new BackJson()
            {
                code = 0,
                data = list
            };
        }

        /// <summary>
        /// 获取排班计划详情
        /// </summary>
        public async Task<BackJson> GetAsync(Guid id)
        {
            var schedule = await _scheduleRepository.FirstOrDefaultAsync(x => x.Id == id);
            if (schedule == null)
            {
                throw new BusinessException(CustomErrorCodes.ScheduleNotExist);
            }
            return new BackJson()
            {
                code = 0,
                data = _mapper.Map<Schedule, ScheduleDto>(schedule)
            };
        }

        /// <summary>
        /// 保存新建
        /// </summary>
        public async Task<BackJson> SubmitCreateAsync(CreateScheduleDto dto, Guid depId, Guid deviceTypeId)
        {
            var department = await _departmentRepository.FirstOrDefaultAsync(x => x.Id == depId);
            if (department == null)
            {
                throw new BusinessException(CustomErrorCodes.DepartmentNotExist);
            }
            var deviceType = await _deviceTypeRepository.FirstOrDefaultAsync(x => x.Id == deviceTypeId);
            if (deviceType == null)
            {
                throw new BusinessException(CustomErrorCodes.DeviceTypeNotExist);
            }
            var sameCodeList = await _scheduleManager.IsCodeNotExist(dto.Code);
            if (sameCodeList.Count>0)
            {
                throw new BusinessException(CustomErrorCodes.CodeAlreadyExist)
                {
                    Data =
                    {
                        { "code",dto.Code}
                    }
                };
            }
            var schedule = _mapper.Map<CreateScheduleDto, Schedule>(dto);
            schedule.DepartmentId = depId;
            schedule.DeviceTypeId = deviceTypeId;
            schedule.Department = department;
            schedule.DeviceType = deviceType;
            await _scheduleRepository.InsertAsync(schedule);
            return new BackJson()
            {
                code = 0,
                msg = "保存成功。"
            };
        }


        /// <summary>
        /// 保存修改
        /// </summary>
        public async Task<BackJson> SubmitEditAsync(ScheduleDto dto, Guid depId, Guid deviceTypeId)
        {
            var department = await _departmentRepository.FirstOrDefaultAsync(x => x.Id == depId);
            if (department == null)
            {
                throw new BusinessException(CustomErrorCodes.DepartmentNotExist);
            }
            var deviceType = await _deviceTypeRepository.FirstOrDefaultAsync(x => x.Id == deviceTypeId);
            if (deviceType == null)
            {
                throw new BusinessException(CustomErrorCodes.DeviceTypeNotExist);
            }

            var schedule = await _scheduleRepository.FirstOrDefaultAsync(x => x.Id == dto.Id);
            if (schedule == null)
            {
                throw new BusinessException(CustomErrorCodes.ScheduleNotExist);
            }

            var sameCodeList = await _scheduleManager.IsCodeNotExist(dto.Code);
            if (sameCodeList.Count>1)
            {
                throw new BusinessException(CustomErrorCodes.CodeAlreadyExist)
                {
                    Data =
                    {
                        { "code",dto.Code}
                    }
                };
            }

            schedule.Name = dto.Name;
            schedule.Code = dto.Code;
            schedule.IsActive = dto.IsActive;
            schedule.Order = dto.Order;
            schedule.Desc = dto.Desc;

            await _scheduleRepository.UpdateAsync(schedule);

            return new BackJson()
            {
                code = 0,
                msg = "保存成功"
            };
        }


        /// <summary>
        /// 禁用/启用
        /// </summary>
        public async Task<BackJson> ToggleDisableAsync(Guid id)
        {
            var schedule = await _scheduleRepository.FirstOrDefaultAsync(x => x.Id == id);
            if (schedule == null)
            {
                throw new BusinessException(CustomErrorCodes.ScheduleNotExist);
            }
            string msg = "已禁用";
            if (!schedule.IsActive)
            {
                msg = "启用成功";
            }
            schedule.IsActive = !schedule.IsActive;
            await _scheduleRepository.UpdateAsync(schedule);
            return new BackJson()
            {
                code = 0,
                msg = msg
            };
        }

        /// <summary>
        /// 删除排班计划
        /// </summary>
        public async Task<BackJson> Delete(Guid id)
        { 
            await _scheduleRepository.DeleteAsync(id);
            return new BackJson()
            {
                code = 0,
                msg = "删除成功"
            };
        }
    }
}
